/**
 * All Rights Reserved , Copyright (C) 2020 , 青岛鼎信通讯股份有限公司
 * BasePermissionManageService
 * 基础权限管理
 * 修改纪录
 * 2020-10-26 版本：1.0 maxiaodong 创建。
 *
 * @version 版本：1.0
 * @author 作者：maxiaodong
 * 创建日期：2020-10-26
 */
package com.topscomm.base.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.topscomm.work.pojo.WorkScheduleEntity;
import org.apache.curator.shaded.com.google.common.base.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.topscomm.base.BaseSystemConst;
import com.topscomm.base.BaseSystemConst.ShareTypeEnum;
import com.topscomm.base.pojo.BasePermissionManageEntity;
import com.topscomm.base.pojo.BaseTeamUserEntity;
import com.topscomm.base.service.IBaseCboUserExtendService;
import com.topscomm.base.service.IBasePermissionManageService;
import com.topscomm.base.service.IBaseTeamInfoService;
import com.topscomm.base.service.IBaseTeamUserService;
import com.topscomm.base.service.impl.auto.BasePermissionManageServiceAuto;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboRoleEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboUserService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.DateUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.common.SessionUserBean;

@Service(value = "basePermissionManageService")
@Scope(value = "singleton")
public class BasePermissionManageService extends BasePermissionManageServiceAuto
		implements IBasePermissionManageService {
	private static final String USERCODES = "usercodes";
	private static final String DEPTCODES = "deptcodes";
	private static final String TEAMIDS = "teamids";
	private static final String ROLEIDS = "roleids";
	private static final String SHARECODES = "sharecodes";
	@Autowired
	private ICboUserService cboUserService;
	@Autowired
	private IBaseTeamUserService baseTeamUserService;
	@Autowired
	private IBaseTeamInfoService baseTeamInfoService;
	@Autowired
	IBaseCboUserExtendService baseCboUserExtendService;
	// 前端传递的selectUser的key值对应关系
	private static Map<String, String> typeList = new HashMap<>();
	static {
		typeList.put(USERCODES, ShareTypeEnum.User);
		typeList.put(DEPTCODES, ShareTypeEnum.Dept);
		typeList.put(TEAMIDS, ShareTypeEnum.Team);
		typeList.put(ROLEIDS, ShareTypeEnum.Role);
		typeList.put(SHARECODES, ShareTypeEnum.Share);
	}

	/**
	 * @description:批量保存
	 * @param sourceId
	 * @param sourceType
	 * @param list
	 * @author: zhanglongfei
	 * @date: 2020年11月2日下午5:30:12
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchSaveList(String sourceId, String sourceType, List<BasePermissionManageEntity> list) {
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendLineSingle("sourcetype='{0}' and sourceid='{1}'", sourceType, sourceId);
		deleteByWhere(sql.toString());
		for (BasePermissionManageEntity item : list) {
			item.setSourceid(sourceId);
			item.setSourcetype(sourceType);
			insert(item);
		}
	}

	/**
	 * 得到批量人员
	 *
	 * @description:
	 * @param paraMap
	 * @return
	 * @author: donghang
	 * @date: 2020年11月3日上午11:51:04
	 * @modify:
	 */
	@Override
	public List<BasePermissionManageEntity> processSelectUsers(Map<String, Object> users, String sourceFlag,
			String sourceUserCodes, String sourceUserNames) {
		List<BasePermissionManageEntity> list = new ArrayList<>();
		if (users == null) {
			return list;
		}
		for (String key : typeList.keySet()) {
			if (users.containsKey(key)) {
				String userCode = ConvertUtil.convertToString(users.get(key));
				if (userCode.length() > 0) {
					BasePermissionManageEntity entity = new BasePermissionManageEntity();
					entity.setShareobjects(userCode);
					entity.setShareobjectsdesc(ConvertUtil
							.convertToString(users.get(key.replace("codes", "").replace("ids", "") + "names")));
					entity.setSharetype(typeList.get(key));
					entity.setSourceflag(sourceFlag);
					entity.setSourceusercodes(sourceUserCodes);
					entity.setSourceusernames(sourceUserNames);
					list.add(entity);
				}
			}
		}
		return list;
	}

	/**
	 * @description: 得到全部的参会人员
	 * @param selectUsers
	 * @return
	 * @author: wanghongwei
	 * @date: 2020-11-3 20:10:42
	 * @modify:
	 */
	@Override
	public List<Map<String, Object>> getAllAttendUser(Map<String, Object> selectUsers) {
		List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
		if (selectUsers == null) {
			return resultList;
		}
		for (String key : typeList.keySet()) {
			if (!selectUsers.containsKey(key)) {
				continue;
			}
			String shareObj = ConvertUtil.convertToString(selectUsers.get(key));
			if (!StringUtil.isEmpty(shareObj)) {
				if (Objects.equal(USERCODES, key)) {
					resultList.addAll(this.baseCboUserExtendService.searchUsersByUserCodes(shareObj));
				} else if (Objects.equal(DEPTCODES, key)) {
					resultList.addAll(this.baseCboUserExtendService.searchUsersByDeptCodes(shareObj));
				} else if (Objects.equal(TEAMIDS, key)) {
					resultList.addAll(this.baseCboUserExtendService.searchUsersByTeamIds(shareObj));
				} else if (Objects.equal(ROLEIDS, key)) {
					resultList.addAll(this.baseCboUserExtendService.searchUserByRoleIds(shareObj));
				} else if (Objects.equal(SHARECODES, key)) {
					resultList.addAll(this.baseCboUserExtendService.searchUsersByUserCodes(shareObj));
				}
			}
		}
		return resultList.stream().distinct().collect(Collectors.toList());
	}

	/**
	 * @description:
	 * @return
	 * @author: donghang
	 * @date: 2020年11月12日下午2:00:12
	 * @modify:
	 */
	public String createUserShareCondition(SessionUserBean sessionUserBean, boolean teamUserTimeValid,
			String beginTimeFieldName) {
		StringBufferProxy sqlWhere = new StringBufferProxy();
		String[] shareobjectsParams = { "','", "shareobjects", "','" };
		// 人员
		sqlWhere.appendSingle("( sharetype='{0}' and  ({1}) like '%{2}%' ) ", ShareTypeEnum.User,
				SQLAdapter.concat(shareobjectsParams), "," + sessionUserBean.getUser().getCode() + ",");
		// 角色
		List<CboRoleEntity> cboRoleEntityList = sessionUserBean.getRoleList();
		for (CboRoleEntity cboRoleEntity : cboRoleEntityList) {
			sqlWhere.appendSingle(" or (sharetype='{0}' and ({1} like '%{2}%')) ", ShareTypeEnum.Role, "shareobjects",
					cboRoleEntity.getId());
		}
		// 部门,包含下级部门
		String deptcodesql = BaseShareManageService.createWhereDeptCheckInclude("shareobjects",
				sessionUserBean.getDept().getCode(), ",");
		if (deptcodesql.length() > 0) {
			sqlWhere.appendSingle(" or (sharetype='{0}' and {1})", ShareTypeEnum.Dept, deptcodesql);
		}
		// 团队查看当前人所在的所有团队
		Map<String, Object> userTeamMap = this.baseTeamInfoService.getUserTeam(sessionUserBean.getUser().getCode());
		for (Map.Entry<String, Object> entry : userTeamMap.entrySet()) {
			String teamId = entry.getKey();
			Map<String, Object> teamMap = (Map<String, Object>) entry.getValue();
			if (teamUserTimeValid == true
					&& !BaseSystemConst.TeamUserTypeEnum.Director
							.equals(ConvertUtil.convertToString(teamMap.get("usertype")))
					&& ConvertUtil.convertToString(teamMap.get("positionbegintime")).length() > 0) {
				sqlWhere.appendSingle(" or ({0} like '%{1}%' and {2}>={3}) ", "shareobjects", teamId,
						beginTimeFieldName,
						SQLAdapter.toDateLong(DateUtil.dateToString(
								DateUtil.stringToDate(ConvertUtil.convertToString(teamMap.get("positionbegintime"))),
								"yyyy-MM-dd HH:mm:ss")));
			} else {
				sqlWhere.appendSingle(" or (sharetype='{0}' and ({1} like '%{2}%')) ", ShareTypeEnum.Team,
						"shareobjects", teamId);
			}
		}
		return sqlWhere.toString();
	}

	/**
	 * @description: 发现所有的人
	 * @param paraMap
	 * @return
	 * @author: maxiaodong
	 * @date: 2020年11月9日下午2:49:39
	 * @modify:
	 */
	@Override
	public Set<String> findAllSharersByMap(Map<String, Object> paraMap) {
		Set<String> sharers = new HashSet<>();
		String deptcodes = ConvertUtil.convertToString(paraMap.get("deptcodes"));
		if (!StringUtil.isEmpty(deptcodes)) {
			String[] shareList = deptcodes.split(",");
			StringBufferProxy deptCodeWhere = new StringBufferProxy();
			for (String share : shareList) {
				deptCodeWhere.appendLineSingle("or code like '{0}%' ", share);
			}
			String where = String.format("deptid in ( select id from cbodept where %s) and dimissiondate is null",
					deptCodeWhere.toString().substring(2));
			// 查找该 下所有人
			List<CboUserEntity> cboUserEntityList = this.cboUserService.queryByWhere(where);
			for (CboUserEntity cboUserEntity : cboUserEntityList) {
				sharers.add(cboUserEntity.getCode());
			}
		}
		String teamids = ConvertUtil.convertToString(paraMap.get("teamids"));
		if (!StringUtil.isEmpty(teamids)) {
			if (teamids.startsWith(",")) {
				teamids = teamids.substring(1);
			}
			if (teamids.endsWith(",")) {
				teamids = teamids.substring(0, teamids.length() - 1);
			}
			List<BaseTeamUserEntity> baseTeamUserEntityList = baseTeamUserService
					.queryByWhere(BaseTeamUserEntity.FieldTeamid + " in (" + teamids
							+ ") and usercode not in (select code from cbouser where  dimissiondate is null)");
			for (BaseTeamUserEntity baseTeamUserEntity : baseTeamUserEntityList) {
				sharers.add(baseTeamUserEntity.getUsercode());
			}
		}
		String roleids = ConvertUtil.convertToString(paraMap.get("roleids"));
		if (!StringUtil.isEmpty(roleids)) {
			if (roleids.startsWith(",")) {
				roleids = roleids.substring(1);
			}
			if (roleids.endsWith(",")) {
				roleids = roleids.substring(0, roleids.length() - 1);
			}
			// 查询角色中的所有人
			List<CboUserEntity> userList = cboUserService
					.queryByWhere("id in ( select userid from CboUserRole where roleid in (" + roleids
							+ ")) and dimissiondate is null");
			for (CboUserEntity cboUserEntity : userList) {
				sharers.add(ConvertUtil.convertToString(cboUserEntity.getCode()));
			}
		}
		String usercodes = ConvertUtil.convertToString(paraMap.get("usercodes"));
		if (!StringUtil.isEmpty(usercodes)) {
			String[] shareList = usercodes.split(",");
			for (int i = 0; i < shareList.length; i++) {
				shareList[i] = "'" + shareList[i] + "'";
			}
			String shareListString = String.join(",", shareList);
			List<CboUserEntity> cboUserEntityList = this.cboUserService
					.queryByWhere("code in (" + shareListString + ")");
			for (CboUserEntity cboUserEntity : cboUserEntityList) {
				// 排除离职人员
				if (cboUserEntity.getDimissiondate() == null) {
					sharers.add(cboUserEntity.getCode());
				}
			}
		}
		String sharecodes = ConvertUtil.convertToString(paraMap.get("sharecodes"));
		if (!StringUtil.isEmpty(sharecodes)) {
			String[] shareList = sharecodes.split(",");
			for (int i = 0; i < shareList.length; i++) {
				shareList[i] = "'" + shareList[i] + "'";
			}
			String shareListString = String.join(",", shareList);
			List<CboUserEntity> cboUserEntityList = this.cboUserService
					.queryByWhere("code in (" + shareListString + ")");
			for (CboUserEntity cboUserEntity : cboUserEntityList) {
				// 排除离职人员
				if (cboUserEntity.getDimissiondate() == null) {
					sharers.add(cboUserEntity.getCode());
				}
			}
		}
		return sharers;
	}

	/**
	 * @description:将BasePermissionManage表的list转前台Map格式，支持多来源并去重
	 * @param list
	 * @return
	 * @author: chengengwei
	 * @date: 2021-2-24
	 * @modify:
	 */
	public Map<String, Object> processToMapUsers(List<BasePermissionManageEntity> list) {
		Map<String, Object> result = new HashMap<>();
		for (BasePermissionManageEntity basePermissionManageEntity : list) {
			if (BaseSystemConst.ShareTypeEnum.Dept.equals(basePermissionManageEntity.getSharetype())) {
				if (result.containsKey("deptcodes")) {
					result.put("deptcodes", result.get("deptcodes") + "," + basePermissionManageEntity.getShareobjects());
					result.put("deptnames", result.get("deptnames") + "," + basePermissionManageEntity.getShareobjectsdesc());
				} else {
					result.put("deptcodes", basePermissionManageEntity.getShareobjects());
					result.put("deptnames", basePermissionManageEntity.getShareobjectsdesc());
				}
			} else if (BaseSystemConst.ShareTypeEnum.User.equals(basePermissionManageEntity.getSharetype())) {
				if (result.containsKey("usercodes")) {
					result.put("usercodes", result.get("usercodes") + "," + basePermissionManageEntity.getShareobjects());
					result.put("usernames", result.get("usernames") + "," + basePermissionManageEntity.getShareobjectsdesc());
				} else {
					result.put("usercodes", basePermissionManageEntity.getShareobjects());
					result.put("usernames", basePermissionManageEntity.getShareobjectsdesc());
				}
			} else if (BaseSystemConst.ShareTypeEnum.Role.equals(basePermissionManageEntity.getSharetype())) {
				if (result.containsKey("roleids")) {
					result.put("roleids", result.get("roleids") + "," + basePermissionManageEntity.getShareobjects());
					result.put("rolenames", result.get("rolenames") + "," + basePermissionManageEntity.getShareobjectsdesc());
				} else {
					result.put("roleids", basePermissionManageEntity.getShareobjects());
					result.put("rolenames", basePermissionManageEntity.getShareobjectsdesc());
				}
			} else if (BaseSystemConst.ShareTypeEnum.Team.equals(basePermissionManageEntity.getSharetype())) {
				if (result.containsKey("teamids")) {
					result.put("teamids", result.get("teamids") + "," + basePermissionManageEntity.getShareobjects());
					result.put("teamnames", result.get("teamnames") + "," + basePermissionManageEntity.getShareobjectsdesc());
				} else {
					result.put("teamids", basePermissionManageEntity.getShareobjects());
					result.put("teamnames", basePermissionManageEntity.getShareobjectsdesc());
				}
			} else if (BaseSystemConst.ShareTypeEnum.Share.equals(basePermissionManageEntity.getSharetype())) {
				if (result.containsKey("sharecodes")) {
					result.put("sharecodes", result.get("sharecodes") + "," + basePermissionManageEntity.getShareobjects());
					result.put("sharenames", result.get("sharenames") + "," + basePermissionManageEntity.getShareobjectsdesc());
				} else {
					result.put("sharecodes", basePermissionManageEntity.getShareobjects());
					result.put("sharenames", basePermissionManageEntity.getShareobjectsdesc());
				}
			}
		}
		Set<String> tempSet = new HashSet<>();
		// 去重
		result.forEach((k, v) -> {
			String[] codes = ((String) v).split(",");
			tempSet.addAll(Arrays.asList(codes));
			result.put(k, tempSet.stream().collect(Collectors.joining(",")));
			tempSet.clear();
		});
		return result;
	}
	/**
	  * 输入用户及对应日程的日程List 返回冲突记录
	  * @author xinfushuo
	  * @param sharers 用户集合
	  * @param workScheduleMapList 日程List
	  * @throws
	  * @return 冲突记录
	  * @date 2022/12/26
	  * @modify
	  */
	@Override
	public List<Map<String,Object>> checkConflict(Set<String> sharers, List<Map<String, Object>> workScheduleMapList){
		// 把所有的查询出来的日程都找到他们的人员，放到一个set中
		List<String> sourceidList = new ArrayList<>();
		for (Map<String, Object> map : workScheduleMapList) {
			sourceidList.add(ConvertUtil.convertToString(map.get(WorkScheduleEntity.FieldId)));
		}
		//查询所有日程关联的basepermission
		StringBufferProxy whereSql = new StringBufferProxy();
		whereSql.appendSingle("sourcetype = 'workSchedule' and ('1',sourceid) in ({0})", sourceidList.stream().map(s->"('1',"+s+")").collect(Collectors.joining(",")));
		List<String> permissionManagementFiledList = new ArrayList<String>();
		permissionManagementFiledList.add(BasePermissionManageEntity.FieldShareobjects);
		permissionManagementFiledList.add(BasePermissionManageEntity.FieldSharetype);
		permissionManagementFiledList.add(BasePermissionManageEntity.FieldSourceid);
		List<Map<String, Object>> basePermissionManageMapList = this
				.queryMapFieldsByWhere(whereSql.toString(), permissionManagementFiledList);
		Map<String, Map<String, Object>> sourceidMap = new HashMap<>();
		//形成一个sourceid ： ShareObj 的map 用来冲突检测
		for (Map<String, Object> basePermissionManageMap : basePermissionManageMapList) {
			String sourceid = ConvertUtil
					.convertToString(basePermissionManageMap.get(BasePermissionManageEntity.FieldSourceid));
			if (sourceidMap.containsKey(sourceid)) {
				// 获取所有共享的类型与对象
				Map<String, Object> map = sourceidMap.get(sourceid);
				this.formShareMap(map, basePermissionManageMap);
			} else {
				Map<String, Object> map = new HashMap<>();
				this.formShareMap(map, basePermissionManageMap);
				sourceidMap.put(ConvertUtil
						.convertToString(basePermissionManageMap.get(BasePermissionManageEntity.FieldSourceid)), map);
			}
		}
		List<Map<String, Object>> resultReturn = new ArrayList<>();
		// 时间冲突检测
		for (Map<String, Object> workScheduleMap : workScheduleMapList) {
			// 首先拿到这个日程的所有共享人
			String sourceidOne = ConvertUtil.convertToString(workScheduleMap.get(WorkScheduleEntity.FieldId));
			if (sourceidMap.containsKey(sourceidOne)) {
				Set<String> sharersOne = this
						.findAllSharersByMap(sourceidMap.get(sourceidOne));
				// 冲突检测
				sharersOne.retainAll(sharers);
				String sharersOneString = String.join("','", new ArrayList<>(sharersOne));
				List<CboUserEntity> CboUserEntityList = this.cboUserService
						.queryByWhere("code in ('" + sharersOneString + "')");
				List<String> sharersOneList = new ArrayList<>(sharersOne);
				Map<String, Object> map = new HashMap<>();
				for (CboUserEntity cboUserEntity : CboUserEntityList) {
					map.put(cboUserEntity.getCode(), cboUserEntity.getName());
				}
				for (String userCodeConflict : sharersOneList) {
					Map<String, Object> resultMapReturn = new HashMap<>();
					resultMapReturn.put("userCodeConflict", userCodeConflict);// 冲突人（单个人）的usercode
					resultMapReturn.put("beginTime", workScheduleMap.get(WorkScheduleEntity.FieldBegintime));
					resultMapReturn.put("endTime", workScheduleMap.get(WorkScheduleEntity.FieldEndtime));
					resultMapReturn.put("scheduleName", workScheduleMap.get(WorkScheduleEntity.FieldName));
					resultMapReturn.put("scheduleId", workScheduleMap.get(WorkScheduleEntity.FieldId));
					resultMapReturn.put("userNameConflict", map.get(userCodeConflict));
					resultReturn.add(resultMapReturn);
				}
			}
		}
		return resultReturn;
	}
	/**
	 * @description: 构成共享类型与共享对象的map
	 * @author: maxiaodong
	 * @date: 2020年11月11日下午5:03:30
	 * @modify:
	 */
	@Override
	public void formShareMap(Map<String, Object> map, Map<String, Object> basePermissionManageMap) {
		String sharetype = ConvertUtil
				.convertToString(basePermissionManageMap.get(BasePermissionManageEntity.FieldSharetype));
		String shareobjects = ConvertUtil
				.convertToString(basePermissionManageMap.get(BasePermissionManageEntity.FieldShareobjects));
		// 把所有的shareobjects全部拆成人。然后打成一个set
		if (sharetype.equals(ShareTypeEnum.Dept)) {
			map.put("deptcodes", shareobjects);
		} else if (sharetype.equals(ShareTypeEnum.Team)) {
			map.put("teamids", shareobjects);
		} else if (sharetype.equals(ShareTypeEnum.Role)) {
			map.put("roleids", shareobjects);
		} else if (sharetype.equals(ShareTypeEnum.User)) {
			map.put("usercodes", shareobjects);
		} else if (sharetype.equals(ShareTypeEnum.Share)) {
			map.put("sharecodes", shareobjects);
		}
	}
}
